﻿/*
 * Copyright Mark Dawson 2008 - http://www.markdawson.org/kit3D
*/

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using SLPhysicsDemo;

namespace Kit3D.Windows.Media
{
    //See: http://msdn.microsoft.com/en-us/library/ms748838.aspx
    public static class CompositionTarget
    {
        private static StoryboardGameLoop _GameLoop;
        private static int frameRate;
        private static DispatcherTimer renderTimer;
        public static event EventHandler Rendering;
        internal static event EventHandler RenderingComplete;

        static CompositionTarget()
        {
            CompositionTarget._FrameRate = 0;
        }

        /// <summary>
        /// Initialize and start the simulation.
        /// </summary>
        private static void RunSimulation()
        {
            _GameLoop = new StoryboardGameLoop(new Button(), frameRate);
            _GameLoop.Update += new GameLoop.UpdateHandler(_GameLoop_Update);
            _GameLoop.Start();
        }

        /// <summary>
        /// The refrsh rate in frames per second - NOT thread safe
        /// </summary>
        public static int _FrameRate
        {
            get { return CompositionTarget.frameRate; }
            set
            {
                if (CompositionTarget._GameLoop != null)
                {
                    CompositionTarget._GameLoop.Stop();
                }
                else
                {
                    if (value == 0)
                        CompositionTarget._GameLoop = new StoryboardGameLoop(new Button());
                    else
                        CompositionTarget._GameLoop = new StoryboardGameLoop(new Button(), 1000.0 / value);
                    
                    CompositionTarget._GameLoop.Update += new GameLoop.UpdateHandler(_GameLoop_Update);
                }

                CompositionTarget.frameRate = value;
                CompositionTarget._GameLoop.Start();
            }
        }

        /// <summary>
        /// This is called by the game loop every frame.
        /// </summary>
        /// <param name="elapsed"></param>
        private static void _GameLoop_Update(TimeSpan elapsed)
        {
            //UpdatePhysics(elapsed);
            renderTimer_Tick(null, null);
        }

        /// <summary>
        /// The refrsh rate in frames per second - NOT thread safe
        /// </summary>
        public static int FrameRate
        {
            get { return CompositionTarget.frameRate; }
            set
            {
                if (CompositionTarget.renderTimer != null)
                {
                    CompositionTarget.renderTimer.Stop();
                }
                else
                {
                    CompositionTarget.renderTimer = new DispatcherTimer();
                    CompositionTarget.renderTimer.Tick += new EventHandler(renderTimer_Tick);
                }

                CompositionTarget.frameRate = value;
                CompositionTarget.renderTimer.Interval = TimeSpan.FromSeconds(1.0 / CompositionTarget.frameRate);
                CompositionTarget.renderTimer.Start();
            }
        }

        private static void renderTimer_Tick(object sender, EventArgs e)
        {
            //All public classes can hook in here
            EventHandler handler = Rendering;
            if (handler != null)
            {
                //TODO: Populate with the correct values
                handler(null, null);
            }

            //Now inform internal classes they can render
            handler = RenderingComplete;
            if (handler != null)
            {
                handler(null, null);
            }
        }

    }
}
